#!/bin/bash
# KernelCheck script v. 1.0.0.7
# Created for KernelCheck Lumen

if [ -z "$1" ]; then
echo
echo "Этот скрипт должен выполняться только с KernelCheck ."
echo
exit
fi

# Define all global variables
FUNCTION=$1
DIR=$2
STABLE=$(head -1 $DIR)
STABLE_URL=$(head -2 $DIR | tail -1)
PATCH=$(head -3 $DIR | tail -1)
PATCH_URL=$(head -4 $DIR | tail -1)
PATCHTYPE=$(head -5 $DIR | tail -1)
CONFIGURE=$(head -6 $DIR | tail -1)
SOUND=$(head -7 $DIR | tail -1)
OPTIMIZE=$(head -8 $DIR | tail -1)
RECONFIGURE=$(head -9 $DIR | tail -1)
NVIDIA=$(head -10 $DIR | tail -1)
FGLRX=$(head -11 $DIR | tail -1)
INSTALLPACKAGE=$(head -12 $DIR | tail -1)
CUSTOM=$(head -13 $DIR | tail -1)
CLEANUP=$(head -14 $DIR | tail -1)
CCJOBS=$(head -15 $DIR | tail -1)

# The name for your kernel - you may edit it
CODENAME="Candela" # The candela is the SI base unit of luminous intensity

# DO NOT EDIT THE COMMAND BELOW; DOING SO MAY CAUSE THE COMPILE PROCESS TO HALT
# If you need an explanation, the codename specified above is removed of spaces
# and converted to lowercase.
CODENAME=$(echo "$CODENAME" | sed 's/ //g' | sed 's/.*/\L&/g')

# Trap signals
trap term_exit TERM HUP INT

function log
{
"$1" | sudo tee -a /var/log/kernelcheck.log
}

function term_exit
{
rm -rf /tmp/$DIR
echo -e "\033[1;31mABORT: interrupted."
echo
exit 2
}

# Function to check the return code of commands
function checkretcode {
ERRORCODE=$?
if [ "$ERRORCODE" -ne 0 ]
then
echo
echo -e "\033[1;31mABORT: $1 returned exit status $ERRORCODE"
echo -e "\033[0m"
touch /tmp/stage-failed.tmp
rm -rf /tmp/$DIR
exit 1
fi
}

# Test to see if the user is using proprietary graphics drivers
function test_graphics {
PROPRIETARY=$(cat /etc/X11/xorg.conf | grep "nvidia" || cat /etc/X11/xorg.conf | grep "fglrx")
if [ "$PROPRIETARY" != "" ]
    then
    if [ "$(cat /etc/X11/xorg.conf | grep "fglrx")" != "" ]; then DRIVER="fglrx"; else DRIVER="nvidia"; fi
    echo
    echo " пропиетарный драйвер [$DRIVER] обнаружен в вашей системе."
    echo "очень реклмендуется переконфигурировать ваш X-сервер для избежания проблем с графикой после перезагрузки."
    echo
    echo -n "Вы хотите переконфигурировать  X server? [Y/n] "
    read -e RECONFIGURE
    case $RECONFIGURE in
        "n" | "no" | "NO" | "No" )
            echo -e "\033[1;31mWARNING: Не выполняем перконфигурацию X-сервера"
            echo -e "\033[0m"
        ;;
        * )
            echo -e "\033[1;32mРеконфигурация X-сервера..."
            echo "Обратите внимание: Вы переустановите ваш видео драйвер после перезагрузки. Нажмите  ENTER для продолжения."
            read
            echo -e "\033[0m"
            dpkg-reconfigure -phigh xserver-xorg
        ;;
    esac
fi
}

function prestage {
echo -e "\033[1;31mPrestage: Housekeeping (this may take a few minutes)"
echo -e "\033[0m"
cd /usr/src/
if [ ! -d oldpackages ]; then mkdir oldpackages; checkretcode prestage; fi
cd /usr/src
sudo find . -maxdepth 1 -name "*.deb" -exec mv {} oldpackages/ \;
checkretcode prestage
rm -rf linux-$STABLE linux
checkretcode prestage

if [ $RECONFIGURE = "True" ]
    then
    echo -e "\033[1;31mЭтап: реконфигурация X-сервера "
    echo -e "\033[0m"
    dpkg-reconfigure -phigh xserver-xorg
    checkretcode prestage
fi
}

function stage1 {
echo -e "\033[1;31mЭтап 1/6: Установка зависимостей"
echo -e "\033[0m"
apt-get update
apt-get install -y --force-yes build-essential bin86 kernel-package libqt3-headers libqt3-mt-dev wget libncurses5 libncurses5-dev
apt-get install -f
checkretcode stage1
exit
}

function stage2 {
echo -e "\033[1;31mЭтап 2/6: Загрузка пакетов"
echo -e "\033[0m"
cd /usr/src
wget -c $STABLE_URL
if [ $PATCH != $STABLE ]; then wget -c $PATCH_URL; checkretcode stage2; fi
exit
}

function stage3 {
cd /usr/src
echo -e "\033[1;31mЭтап 3: Распаковка пакетов (это может занять несколько минут)"
echo -e "\033[0m"
tar -xjf linux-$STABLE.tar.bz2
checkretcode stage3
cd /usr/src
rm -rf linux
ln -s /usr/src/linux-$STABLE linux
patch_command=$(echo $PATCH | grep mm)
if [ "$patch_command" != "" ]; then cd /usr/src/linux; bzcat /usr/src/$PATCH.bz2 | patch -p1
else
if [ $PATCH != $STABLE ]; then cd /usr/src/linux; bzcat /usr/src/patch-$PATCH.bz2 | patch -p1; fi
fi
checkretcode stage3
exit
}

function stage4 {
cd /usr/src/linux
echo ""
echo -e "\033[1;31mStage 4/6: конфигурация нового ядра"
echo -e "\033[0m"
cp /boot/config-`uname -r` .config
# DISABLE CONFIG_XEN >> KERNEL WILL NOT COMPILE
sed -i 's/CONFIG_XEN=y/\#CONFIG_XEN is not set/g' .config
# Initializes HD sound
if [ $SOUND = "True" ]
    then
    sed -i 's/\# CONFIG_SND is not set/CONFIG_SND=m\nCONFIG_SND_HDA_INTEL=m/g' .config
    sed -i 's/\# CONFIG_SND_USB_AUDIO is not set/CONFIG_SND_USB_AUDIO=m/g' .config
fi
# Optimizes kernel
grep "# CONFIG_HZ_1000 is not set" .config
if [ $? = 0 ] && [ $OPTIMIZE = "True" ]
    then
    sed -i 's/\# CONFIG_HZ_1000 is not set/CONFIG_HZ_1000=y/g' .config
    REPLACE_HZ=$(grep "CONFIG_HZ=" .config | sed 's/CONFIG_HZ=\(.*\)/\1/g')
    sed -i "s/CONFIG_HZ_$REPLACE_HZ=y/\# CONFIG_HZ_$REPLACE_HZ is not set/g" .config
    sed -i "s/CONFIG_HZ=$REPLACE_HZ/CONFIG_HZ=1000/g" .config
fi
grep "# CONFIG_DEFAULT_CFQ is not set" .config || grep "CONFIG_IOSCHED_AS=y" .config || grep "CONFIG_IOSCHED_DEADLINE=y" .config
if [ $? = 0 ] && [ $CUSTOM != "True" ] && [ $OPTIMIZE = "True" ]
    then
    sed -i 's/\# CONFIG_DEFAULT_CFQ is not set/CONFIG__DEFAULT_CFQ=y/g' .config
    sed -i "s/CONFIG_DEFAULT_AS=y/\# CONFIG_DEFAULT_AS is not set/g" .config
    sed -i "s/CONFIG_DEFAULT_DEADLINE=y/\# CONFIG_DEFAULT_DEADLINE is not set/g" .config
    sed -i "s/CONFIG_IOSCHED_AS=y/\# CONFIG_IOSCHED_AS is not set/g" .config
    sed -i "s/CONFIG_IOSCHED_DEADLINE=y/\# CONFIG_IOSCHED_DEADLINE is not set/g" .config
    REPLACE_IOSCHED=$(grep "CONFIG_DEFAULT_IOSCHED=" .config | sed 's/CONFIG_DEFAULT_IOSCHED=\(.*\)/\1/g')
    sed -i "s/CONFIG_DEFAULT_IOSCHED=$REPLACE_IOSCHED/CONFIG_DEFAULT_IOSCHED=\"cfq\"/g" .config
fi
# Finished optimizing
yes "" | make oldconfig
if [ $SOUND = "True" ]
    then
    awk '/# PCI devices/{f=1}
    f && !/^$/ && /CONFIG/ && /is not set/ && !/SND_HDA/  {
     gsub(/^# | is not set/,"")
     print $0"=m"
     next
    }
    f && /^$/{ f=0}1' .config > kcheck.conf
    mv kcheck.conf .config
    yes "" | make oldconfig
fi
if [ $CONFIGURE = "True" ]
then make xconfig
fi
echo ""
exit
}

function stage5 {
cd /usr/src/linux
echo -e "\033[1;31mStage 5/6: очистка перед построением"
echo -e "\033[0m"
make-kpkg clean
checkretcode stage5
echo ""
exit
}

function stage6 {
cd /usr/src/linux
echo -e "\033[1;31mStage 6/6:построение нового ядра"
echo -e "\033[0m"
INSTALL_MOD_STRIP=1 CONCURRENCY_LEVEL=$CCJOBS make-kpkg --initrd --append-to-version=-$CODENAME kernel_image kernel_headers modules_image
checkretcode stage6
test_graphics
exit
}

function stage7 {
cd /usr/src
echo -e "\033[1;31mзавершение: установка нового пакета"
echo -e "\033[0m"
echo "должны быть (установлены и) удалены nvidia-common для инсталяции ядра"
check=$(aptitude search '~i ^nvidia-common$')
apt-get install -y --force-yes nvidia-common
dpkg -P nvidia-common
dpkg -i linux-image-$PATCH*.deb
dpkg -i linux-headers-$PATCH*.deb
apt-get install -f
if [ "$check" != "" ]
    then
    apt-get install -y --force-yes nvidia-common
fi
checkretcode dpkg
# Fix symlinks
rm -f /lib/modules/$PATCH-$CODENAME/source /lib/modules/$PATCH-$CODENAME/build
ln -s /usr/src/linux-headers-$PATCH-$CODENAME /lib/modules/$PATCH-$CODENAME/source
ln -s /usr/src/linux-headers-$PATCH-$CODENAME /lib/modules/$PATCH-$CODENAME/build
exit
}

function stage8 {
cd /usr/src
echo -e "\033[1;31mчистка исходников ядра"
echo -e "\033[0m"
rm -rf /usr/src/linux /usr/src/linux-$STABLE
checkretcode "rm"
exit
}

function nvidia {
    echo -e "\033[1;31mполучение последнего драйвера Nvidia..."
    echo -e "\033[0m"
    
    NVIDIA_VERSION=$(head -16 $DIR | tail -1)
    NVIDIA_URL=$(head -17 $DIR | tail -1)
    NVIDIA_FILE=$(head -18 $DIR | tail -1)

    if [ -z $NVIDIA_VERSION ]; then echo 'версия nVidia  драйвера не установлена'; checkretcode nvidia; exit
    else echo "версия nVidia драйвера  для получения: $NVIDIA_VERSION ..."; fi
    if [ -z $NVIDIA_URL ]; then echo 'URL с nVidia драйвером не известна.'; checkretcode nvidia; exit; fi
    if [ -z $NVIDIA_FILE ]; then echo 'Имя файла драйвера не определена.'; checkretcode nvidia; exit; fi

    cd '/usr/src'

    if [ ! -e $NVIDIA_FILE ]; then
        wget -c $NVIDIA_URL -O $NVIDIA_FILE

        if [ -e /usr/src/nvidia-driver ]; then
            rm -rf nvidia-driver
        fi

        ln -s /usr/src/$NVIDIA_FILE /usr/src/nvidia-driver

    else
        if [ ! -e /usr/src/nvidia-driver ]; then
            ln -s /usr/src/$NVIDIA_FILE /usr/src/nvidia-driver
        fi
    fi

    if [ -e /usr/src/nvidia-driver ]; then

        DRIVER=/usr/src/nvidia-driver
        NVIDIA_INSTALLED_VERSION=$(sh /usr/src/nvidia-driver -i | grep 'version' | sed -r 's/.+version: //g' | sed -r 's/\)\.//g')

        echo ""
        echo "Удаление всех nVidia-пакетов"
        apt-get remove -y --force-yes "nvidia-*"
        echo -e "\033[1;32m"
        echo "Ваш /etc/rc.local перемещается на время инсталляции"
        echo "the nVidia драйвер перезагружается.он будет работать нормально после перезагрузки."
        echo "Загрузите новое ядро через меню GRUB ."
        echo -e "\033[0m"
        echo -n "Нажмите ENTER для полдтверждения."
        read enter

        mv /etc/rc.local /etc/rc.local.backup-kernelcheck
        touch /etc/rc.local
        chmod u+x /etc/rc.local

        if [ $NVIDIA_INSTALLED_VERSION = $NVIDIA_VERSION ]
            then
                TESTLINE="sh /usr/src/nvidia-driver -a -q -K --kernel-source-path=/usr/src/linux-headers-$PATCH-$CODENAME || { echo \"nVidia installer failed!\"; dpkg-reconfigure -phigh xserver-xorg; mv /etc/rc.local.backup-kernelcheck /etc/rc.local; reboot; }"
                TESTLINE2=""
            else
                TESTLINE="sh /usr/src/nvidia-driver -a -q --uninstall"
                TESTLINE2="sh /usr/src/nvidia-driver -a -q --kernel-source-path=/usr/src/linux-headers-$PATCH-$CODENAME || { echo \"nVidia installer failed!\"; dpkg-reconfigure -phigh xserver-xorg; mv /etc/rc.local.backup-kernelcheck /etc/rc.local; reboot; }"
        fi

        cat <<EOF > /etc/rc.local
#!/bin/bash -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# This script is not the original rc.local file; rather it is an
# implementation of KernelCheck to install the nVidia driver for a new
# kernel. Any problems with this script should be reported to the
# authors of KernelCheck.
if [ "\`uname -r\`" = "$PATCH-$CODENAME" ]
    then
    echo "останавливаем оконный менеджер"
    stopx=echo $(cat /etc/X11/default-display-manager | sed -r 's/.+\//\/etc\/init\.d\//g' | sed 's/.*/& stop/')
    echo "переходим на виртуальный терминал № 8"
    chvt 8
    echo "начинается инсталяция"
    $TESTLINE
    $TESTLINE2
    nvidia-xconfig
    echo "nVidia-скрипт завершен."
    echo "выполнение оригинального rc.local"
    /etc/rc.local.backup-kernelcheck
    mv /etc/rc.local.backup-kernelcheck /etc/rc.local
    echo "рестарт оконного менеджера"
    restartx=echo $(cat /etc/X11/default-display-manager | sed -r 's/.+\//\/etc\/init\.d\//g' | sed 's/.*/& start/')
fi

exit 0
EOF
    fi

    checkretcode nvidia
    exit
}

case $FUNCTION in
    prestage) log prestage
    ;;
    stage1) log stage1
    ;;
    stage2) log stage2
    ;;
    stage3) log stage3
    ;;
    stage4) log stage4
    ;;
    stage5) log stage5
    ;;
    stage6) log stage6
    ;;
    stage7) log stage7
    ;;
    stage8) log stage8
    ;;
    nvidia) log nvidia
esac
